<template>
  <div>
    <!-- Breadcrumb Navigation area -->
    <el-breadcrumb separator="/">
      <el-breadcrumb-item :to="{ path: '/home' }">Home</el-breadcrumb-item>
      <el-breadcrumb-item>Power</el-breadcrumb-item>
      <el-breadcrumb-item>Roles</el-breadcrumb-item>
    </el-breadcrumb>

    <!-- Card view area -->
    <el-card>
      <!-- Add role btn area -->
      <el-row>
        <el-col>
          <el-button type="primary">Add Role</el-button>
        </el-col>
      </el-row>
      <!-- roles list -->
      <el-table :data="roleList" style="width: 100%" border stripe>
        <!-- Expandable column：Permissions view of role -->
        <el-table-column type="expand" label="-" width="45px">
          <template slot-scope="sp">
            <div>
              <el-row
                v-for="(item1, idx1) in sp.row.children"
                :key="item1.id"
                :class="{border_line_top: idx1 == 0, border_line_bottom: true, vcenter: true}"
              >
                <!-- the column for render 1 level Authority -->
                <el-col :span="5">
                  <el-tag closable @close="removeRightById(item1, sp.row)">{{item1.authName}}</el-tag>
                  <i class="el-icon-caret-right"></i>
                </el-col>
                <!-- the column for render 2、3 level Authority -->
                <el-col :span="19">
                  <!-- 2 level -->
                  <el-row
                    v-for="(item2, idx2) in item1.children"
                    :key="item2.id"
                    :class="{border_line_top: idx2 != 0, vcenter: true}"
                  >
                    <el-col :span="7">
                      <el-tag
                        type="success"
                        closable
                        @close="removeRightById(item2, sp.row)"
                      >{{item2.authName}}</el-tag>
                      <i class="el-icon-caret-right"></i>
                    </el-col>
                    <el-col :span="17">
                      <!-- 3 level -->
                      <el-tag
                        v-for="item3 in item2.children"
                        :key="item3.id"
                        type="warning"
                        closable
                        @close="removeRightById(item3, sp.row)"
                      >{{item3.authName}}</el-tag>
                    </el-col>
                  </el-row>
                </el-col>
              </el-row>
              <!-- <pre>{{sp.row}}</pre> -->
            </div>
          </template>
        </el-table-column>
        <!-- index colnum -->
        <el-table-column type="index" label="#"></el-table-column>
        <el-table-column prop="roleName" label="Role Name"></el-table-column>
        <el-table-column prop="roleDesc" label="Role Description"></el-table-column>
        <el-table-column label="Operating" width="299px">
          <template slot-scope="sp">
            <!-- edit btn -->
            <el-tooltip
              class="item"
              effect="dark"
              :content="'Edit ' + sp.row.roleName"
              placement="top-start"
              :enterable="false"
            >
              <el-button type="primary" icon="el-icon-edit" size="mini">Edit</el-button>
            </el-tooltip>
            <!-- deltet btn -->
            <el-tooltip
              class="item"
              effect="dark"
              :content="'Delete ' + sp.row.roleName"
              placement="top-start"
              :enterable="false"
            >
              <el-button type="danger" icon="el-icon-delete" size="mini">Delete</el-button>
            </el-tooltip>
            <!-- assigning roles btn -->
            <el-tooltip
              class="item"
              effect="dark"
              :content="'set rights for ' + sp.row.roleName"
              placement="top-start"
              :enterable="false"
            >
              <el-button
                type="warning"
                icon="el-icon-setting"
                size="mini"
                @click="showSetRightsDialog(sp.row)"
              >Set Rights</el-button>
            </el-tooltip>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!-- set right dialog -->
    <el-dialog title="Set Rights" :visible.sync="setRightsDialogVisible" width="57%">
      <!-- tree vie of all rights -->
      <el-tree
        :data="rightTreeList"
        :props="treeProps"
        show-checkbox
        node-key="id"
        default-expand-all
        :default-checked-keys="defaultKeys"
        ref="treeRef"
      ></el-tree>
      <span slot="footer" class="dialog-footer">
        <el-button @click="setRightsDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="allotRights">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  data() {
    return {
      roleList: [],
      setRightsDialogVisible: false,
      rightTreeList: [],
      isFirstGetRightTreeList: true,
      treeProps: {
        label: 'authName',
        children: 'children'
      },
      /* id arrays of default checked node */
      defaultKeys: [],
      /* curr operating role's id */
      roleId: ''
    }
  },
  methods: {
    async getRoleList() {
      const rs = await this.$http.get('roles')
      if (rs.meta.status !== 200) return this.$msg.error(rs.meta.msg)
      this.roleList = rs.data
    },
    async removeRightById(right, role) {
      /* pop window  ask user */
      const confirmResult = await this.$confirm(
        'You will be deleting {' +
          right.authName +
          '} right, the operation unrecoverable, you sure?',
        'Warning',
        {
          confirmButtonText: 'I Sure',
          cancelButtonText: 'Cancel',
          type: 'warning'
        }
      ).catch(err => err)

      /* if user cancel: tip & do noting */
      if (confirmResult !== 'confirm') {
        return this.$msg.info('Canceled')
      }
      /* delete right from server */
      const rs = await this.$http.delete(`roles/${role.id}/rights/${right.id}`)
      if (rs.meta.status !== 200) this.$msg.error(rs.meta.msg)
      this.$msg.success(rs.meta.msg)
      /* update role's rights */
      role.children = rs.data
    },
    async showSetRightsDialog(role) {
      /* save role id */
      this.roleId = role.id
      /* get right list */
      if (this.isFirstGetRightTreeList) {
        console.log('first get right tree list...')
        this.isFirstGetRightTreeList = false
        var tryCount = 5
        while (tryCount--) {
          const rs = await this.$http.get('rights/tree')
          /* faild, retry */
          if (rs.meta.status !== 200) {
            this.$msg.error(
              rs.meta.msg +
                '--> Retrying.. number of remaining attempts:' +
                tryCount
            )
            continue
          }
          /* success, break */
          this.rightTreeList = rs.data
        }
      } else {
        /* not the first, take the local data, clone a new object ref */
        this.rightTreeList = JSON.parse(JSON.stringify(this.rightTreeList))
      }
      this.defaultKeys = [] // clean
      this.getLeafKeys(role, this.defaultKeys)
      // console.log(this.defaultKeys)
      this.setRightsDialogVisible = true
    },
    /* get all 3 level rights(leaf node) by recursive
     * and save to 'defaultKeys'
     */
    getLeafKeys(node, arr) {
      // 如果当前 node 节点不包含 children 属性，则是三级节点
      if (!node.children) {
        return arr.push(node.id)
      }
      node.children.forEach(item => this.getLeafKeys(item, arr))
    },
    async allotRights() {
      const keys = [
        ...this.$refs.treeRef.getHalfCheckedKeys(),
        ...this.$refs.treeRef.getCheckedKeys()
      ]
      const keysStr = keys.join(',')

      const rs = await this.$http.post(`roles/${this.roleId}/rights`, {
        rids: keysStr
      })
      if (rs.meta.status !== 200) return this.$msg.error(rs.meta.msg)
      this.$msg.success(rs.meta.msg)
      this.getRoleList()
      this.setRightsDialogVisible = false
    }
  },
  created() {
    this.getRoleList()
  }
}
</script>

<style lang="less" scoped>
.el-tag {
  margin: 9px;
}
.border_line_top {
  border-top: 1px solid #eeeeee;
}
.border_line_bottom {
  border-bottom: 1px solid #eeeeee;
}
.vcenter {
  display: flex;
  align-items: center;
}
</style>
